#include "gameinterface.h"

void CGameInterface::Init()
{

	m_pFrameScene = new CFrameScene;
	m_pGameRules = new CGameRules;
	
	m_pPlayerEntity = NULL;
	m_pGameCamera = NULL;
	m_pGameMap = NULL;

	 m_bPlayerRefreshed = false;
	
	m_NextMap = "";
	m_CurMap = "";
	m_PreviousMap = "";
	
	InitGameRules();
	LuaInit();

	CreateLuaHooks();
	CreateLuaEntityHooks();
	
	SetBattleSystemEntityInterface( this );

}

CGameInterface::~CGameInterface()
{

	delete m_pFrameScene;
	delete m_pGameRules;
	delete m_pBattleSystem;
	delete m_pCollisionSystem;
	delete m_pShaderSystem;
	
}

void CGameInterface::CreateSubSystems()
{
	
	m_pCollisionSystem = new CCollisionSystem( m_pEntityFactory );
	m_pBattleSystem = new CBattleSystem( m_pEntityFactory );
	m_pShaderSystem = new CShaderSystem();

	m_pBattleSystem->InitResources();
	
}

void CGameInterface::InitShaders()
{
	
	m_pShaderSystem->CreateProgram( "shaders/vertex.v", "shaders/fragment.f" );
	m_pShaderSystem->CreateProgram( "shaders/vertex.v", "shaders/st_fragment.f" );

	Draw::SetBlankPixel( Graphics()->Find( "Graphics/pixel.png" )->GetUint( 0 ) );
	
	Draw::SetShaderSystem( m_pShaderSystem, 0 );
	
}
	
void CGameInterface::InitFontResources()
{

	Graphics()->LoadFont( "Uni10", "Graphics/Fonts/uni05_53.ttf", 11 );
	Graphics()->LoadFont( "Uni14", "Graphics/Fonts/uni05_53.ttf", 14 );
	Graphics()->LoadFont( "Uni14Bold", "Graphics/Fonts/uni05_63.ttf", 12 );
	Graphics()->LoadFont( "Uni16Bold", "Graphics/Fonts/uni05_53.ttf", 16 );
	Graphics()->LoadFont( "Uni26Bold", "Graphics/Fonts/uni05_63.ttf", 26 );
	
}

void CGameInterface::AddBattleEntity( int entclass, std::string type )
{
	
	CBattleEntity * e = m_pBattleSystem->AddBattleEntity( entclass, type );

	Lua::AddEntityToBattleTable( entclass, e->GetUniqueID(), e->GetBattleData()->GetLuaDataTable() );
	
}

void CGameInterface::InitGameRules()
{

	m_pGameRules->SetGameRule( "Gravity", 1 );
	m_pGameRules->SetGameRule( "CanMove", 1 );
	
}

void CGameInterface::LoadMap( std::string dir )
{
	
	if( m_pGameMap != NULL )
	{
		
		delete m_pGameMap;
		m_pGameMap = NULL;
		
	}
	
	m_bPlayerRefreshed = true;
	m_pPlayerEntity = NULL;
	m_pEntityFactory->GetStateVec()->RemoveAllEntities();
	
	Draw::SetShaderSystem( m_pShaderSystem, 1 );
	Draw::InitShaderValues( 1 );
	
	m_pGameMap = new CMap;
	m_pGameMap->SetEntityInterface( this );
	m_pGameMap->Load( dir );
	
	Draw::SetShaderSystem( m_pShaderSystem, 0 );
	Draw::InitShaderValues( 0 );
	
	RegisterNameSpace( m_pLuaState, "Level" );
	RegisterNameSpace( m_pLuaState, "MapEvents" );
	
	std::string luadir = dir.substr( 0, dir.length() - 3 ) + "lua";
	
	OpenScript( luadir.c_str() );
	
	m_pCollisionSystem->SetGameMap( m_pGameMap );
	
	m_PreviousMap = m_CurMap;
	m_CurMap = dir.substr( 5, dir.find( ".map" ) - 5 );
	
	Vector2D tl = m_pGameMap->GetTopLeftPoint();
	
	m_pGameCamera->SetTopLeftBounds( tl.x, tl.y );
	m_pGameCamera->SetBottomRightBounds( m_pGameMap->GetMapPixelWidth(), m_pGameMap->GetMapPixelHeight() );
	
	CallLevelHook( "Loaded" );
	
}

bool CGameInterface::ChangeMap()
{

	if( m_NextMap != "" )
	{
		
		LoadMap( m_NextMap );
		m_NextMap = "";
		
		return true;
		
	}
	
	return false;
	
}

void CGameInterface::Think()
{
	
}

CEntity * CGameInterface::CreateEntity()
{
	
	CEntity * e = new CEntity;
	
	m_pEntityFactory->GetStateVec()->AddEntity( e );
	
	return e;
	
}

CEntity * CGameInterface::GetPlayer()
{
	
	if( m_pPlayerEntity )
		return m_pPlayerEntity;
	
	CEntity * p = CreateEntity();
	
	CGraphicsFactory * gfx = m_pGraphicsFactory;
	
	CMaterial * down = gfx->Find(  "Graphics/Sprites/Sorin/sorin16bit_front.spr" );
	CMaterial * left = gfx->Find(  "Graphics/Sprites/Sorin/sorin16bit_left.spr" );
	CMaterial * up = gfx->Find(  "Graphics/Sprites/Sorin/sorin16bit_back.spr" );
	CMaterial * down_run = gfx->Find(  "Graphics/Sprites/Sorin/sorin16bit_frontrun.spr" );
	CMaterial * left_run = gfx->Find(  "Graphics/Sprites/Sorin/sorin16bit_leftrun.spr" );
	
	p->SetPos( 0, 0 );
	//p->SetSizeOverride( 69, 107 );
	
	p->BindSprite( down, SB_DOWN, true );
	p->BindSprite( up, SB_UP );
	p->BindSprite( left, SB_LEFT );
	p->BindSprite( down_run, SB_DOWNRUN );
	p->BindSprite( left_run, SB_LEFTRUN );
	
	p->AddSprite( gfx->Find( "Graphics/Sprites/Sorin/sorin16bit_frontshiver.spr" ) );
	p->AddSprite( gfx->Find( "Graphics/Sprites/Sorin/sorin16bit_fallen.png" ) );
	
	p->Scale( 1.7, 1.7 );
	p->FitCollisionBoxToSprite( 0, 0.3f, .4f );
	p->ShiftCollisionBoxToBottom();
	
	p->SetHasShadow( true );
	
	m_pPlayerEntity = p;
	
	p->SetShadowOffset( 4, -4 );
	
	p->SetClassID( CID_PLAYER );
	
	m_pCollisionSystem->SetPlayer( p );
	
	return p;
	
}